use crate::src::struct_and_type::{Queue, QueueEntry, QueueValue};

extern "C" {
    fn malloc(_: u64) -> *mut ();
    fn free(_: *mut ());
}
#[no_mangle]
pub extern "C" fn queue_new() -> *mut Queue {
    let mut queue: *mut Queue = 0 as *mut Queue;
    queue = (unsafe { malloc(::core::mem::size_of::<Queue>() as u64) }) as *mut Queue;
    if queue.is_null() {
        return 0 as *mut Queue;
    }
    (unsafe { (*queue).head = 0 as *mut QueueEntry });
    (unsafe { (*queue).tail = 0 as *mut QueueEntry });
    return queue;
}
#[no_mangle]
pub extern "C" fn queue_free(mut queue: *mut Queue) {
    while queue_is_empty(queue) == 0 {
        queue_pop_head(queue);
    }
    (unsafe { free(queue as *mut ()) });
}
#[no_mangle]
pub extern "C" fn queue_push_head(mut queue: *mut Queue, mut data: QueueValue) -> i32 {
    let mut new_entry: *mut QueueEntry = 0 as *mut QueueEntry;
    new_entry = (unsafe { malloc(::core::mem::size_of::<QueueEntry>() as u64) }) as *mut QueueEntry;
    if new_entry.is_null() {
        return 0;
    }
    (unsafe { (*new_entry).data = data });
    (unsafe { (*new_entry).prev = 0 as *mut QueueEntry });
    (unsafe { (*new_entry).next = (*queue).head });
    if (unsafe { (*queue).head }).is_null() {
        (unsafe { (*queue).head = new_entry });
        (unsafe { (*queue).tail = new_entry });
    } else {
        (unsafe { (*(*queue).head).prev = new_entry });
        (unsafe { (*queue).head = new_entry });
    }
    return 1;
}
#[no_mangle]
pub extern "C" fn queue_pop_head(mut queue: *mut Queue) -> QueueValue {
    let mut entry: *mut QueueEntry = 0 as *mut QueueEntry;
    let mut result: QueueValue = core::ptr::null_mut();
    if queue_is_empty(queue) != 0 {
        return core::ptr::null_mut();
    }
    entry = unsafe { (*queue).head };
    (unsafe { (*queue).head = (*entry).next });
    result = unsafe { (*entry).data };
    if (unsafe { (*queue).head }).is_null() {
        (unsafe { (*queue).tail = 0 as *mut QueueEntry });
    } else {
        (unsafe { (*(*queue).head).prev = 0 as *mut QueueEntry });
    }
    (unsafe { free(entry as *mut ()) });
    return result;
}
#[no_mangle]
pub extern "C" fn queue_peek_head(mut queue: *mut Queue) -> QueueValue {
    if queue_is_empty(queue) != 0 {
        return core::ptr::null_mut();
    } else {
        return unsafe { (*(*queue).head).data };
    };
}
#[no_mangle]
pub extern "C" fn queue_push_tail(mut queue: *mut Queue, mut data: QueueValue) -> i32 {
    let mut new_entry: *mut QueueEntry = 0 as *mut QueueEntry;
    new_entry = (unsafe { malloc(::core::mem::size_of::<QueueEntry>() as u64) }) as *mut QueueEntry;
    if new_entry.is_null() {
        return 0;
    }
    (unsafe { (*new_entry).data = data });
    (unsafe { (*new_entry).prev = (*queue).tail });
    (unsafe { (*new_entry).next = 0 as *mut QueueEntry });
    if (unsafe { (*queue).tail }).is_null() {
        (unsafe { (*queue).head = new_entry });
        (unsafe { (*queue).tail = new_entry });
    } else {
        (unsafe { (*(*queue).tail).next = new_entry });
        (unsafe { (*queue).tail = new_entry });
    }
    return 1;
}
#[no_mangle]
pub extern "C" fn queue_pop_tail(mut queue: *mut Queue) -> QueueValue {
    let mut entry: *mut QueueEntry = 0 as *mut QueueEntry;
    let mut result: QueueValue = core::ptr::null_mut();
    if queue_is_empty(queue) != 0 {
        return core::ptr::null_mut();
    }
    entry = unsafe { (*queue).tail };
    (unsafe { (*queue).tail = (*entry).prev });
    result = unsafe { (*entry).data };
    if (unsafe { (*queue).tail }).is_null() {
        (unsafe { (*queue).head = 0 as *mut QueueEntry });
    } else {
        (unsafe { (*(*queue).tail).next = 0 as *mut QueueEntry });
    }
    (unsafe { free(entry as *mut ()) });
    return result;
}
#[no_mangle]
pub extern "C" fn queue_peek_tail(mut queue: *mut Queue) -> QueueValue {
    if queue_is_empty(queue) != 0 {
        return core::ptr::null_mut();
    } else {
        return unsafe { (*(*queue).tail).data };
    };
}
#[no_mangle]
pub extern "C" fn queue_is_empty(mut queue: *mut Queue) -> i32 {
    return ((unsafe { (*queue).head }) == core::ptr::null_mut() as *mut QueueEntry) as i32;
}
